#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define INIT_SIZE 10   //初始化表的长度
#define DATA_TYPE int  //数据类型

typedef struct sqlist
{
    int len;           //当前实际数据的长度
    int max_len;       //保存当前表的总长度
    DATA_TYPE *data;   //需要动态分配的
}sqlist,*p_sqlist;     //将struct sqlist * 类型(结构体指针类型) 重命名为p_sqlist类型

//创建一个空表
int creat_sqlist(p_sqlist L)//struct sqlist * L 等价于 p_sqlist L
{
    L->data=(DATA_TYPE *)malloc(sizeof(DATA_TYPE)*INIT_SIZE);//分配INIT_SIZE*sizeof(DATE_TYPE)空间给L->data
    if(L->data==NULL)
    {
        printf("malloc failed\n");
        return -1;
    }
    //将当前表中的数据初始为0
    memset(L->data,0,sizeof(DATA_TYPE)*INIT_SIZE);//清空数据为0
    //表的总允许长度
    L->max_len=INIT_SIZE;
    L->len=0;
    return 0;
}

//尾部添加一个数据
int tail_insert_data_tolist(DATA_TYPE data,p_sqlist L)
{
    //先判断是否为空表
    if(L->data==NULL)
    {
        printf("list is null\n");
        return -1;
    }
    //判断
    if(L->len>=L->max_len)
    {
        printf("list is full\n");
        return -1;
    }
    //插入数据
    L->data[L->len++]=data;
    return 0;
}
//中间指定位置插入一个数据 失败：返回 -1  成功：返回 0  如果位置从 1 开始数
int pos_insert_data_tolist(DATA_TYPE data,p_sqlist L,int pos)
{
    if(L->data==NULL)
    {
        printf("list is NULL\n");
        return -1;
    }
    if(L->len>=L->max_len)//已经满了
    {
        printf("list is full\n");
        return -1;
    }
    //pos是否合法
    if(pos>L->max_len||pos<1||pos>L->len+1)
    {
        printf("pos is error\n");
        return -1;
    }
    //将data插入表中
    int i;
    for(i=L->len;i>=pos;i--)
    {
        L->data[i]=L->data[i-1];
    }
    L->data[pos-1]=data;
    L->len++;
    return 0;
}
//删除一个数据
int pos_delet_data_fromlist(DATA_TYPE data,p_sqlist L)
{
    if(L->len==0||L->data==NULL)//空表
    {
       printf("list is null\n");
       return -1;
    }
    int i;
    for (i = 0; i < L->len; i++)
    {
        if(data==L->data[i])
        {
            break;
        }
    }
    //如果没有找到数据 表示改数据不在表中 返回-1
    if(i==L->len)
    {
        printf("data is not find\n");
        return -1;
    }
    for (; i <L->len-1; i++)
    {
        L->data[i]=L->data[i+1];
    }
    memset(&L->data[L->len-1],0,sizeof(DATA_TYPE));
    L->len--;
    return 0;
}
//遍历
int show_list(p_sqlist L)
{
    if(L->len==0||L->data==NULL)
    {
        printf("list is null\n");
        return -1;
    }
   
    printf("show list data:\n");
    for(int i=0;i<L->len;i++)
    {
        printf("%d ",L->data[i]);
    }
    printf("\n");
    return 0;
}
//扩容
int add_size_forlist(int size,p_sqlist L)
{
    L->data=(DATA_TYPE*)realloc(L->data,sizeof(DATA_TYPE)*(L->max_len+size));
    if (L->data==NULL)
    {
        printf("realloc faild\n");
        return -1;
    }
    
    L->max_len+=size;
    return 0;
}

int main(int argc, char const *argv[])
{
    sqlist list;//结构体类型变量  
    creat_sqlist(&list);//创建一个表
    tail_insert_data_tolist(1,&list);
    tail_insert_data_tolist(2,&list);
    tail_insert_data_tolist(3,&list);
    tail_insert_data_tolist(4,&list);
    tail_insert_data_tolist(5,&list);
    tail_insert_data_tolist(6,&list);
    // tail_insert_data_tolist(7,&list);
    // tail_insert_data_tolist(8,&list);
    // tail_insert_data_tolist(9,&list);
    // tail_insert_data_tolist(10,&list);
    // tail_insert_data_tolist(11,&list);
    show_list(&list);
    pos_insert_data_tolist(100,&list,5);
    show_list(&list);
    pos_insert_data_tolist(110,&list,1);
    show_list(&list);
    pos_insert_data_tolist(120,&list,9);
    show_list(&list);
    pos_insert_data_tolist(220,&list,10);
    show_list(&list);
    printf("在第11个位置插入数据\n");
    pos_insert_data_tolist(220,&list,11);
    show_list(&list);
    //扩容
    add_size_forlist(2,&list);
    printf("扩容后继续在第11个位置插入数据");
    pos_insert_data_tolist(220,&list,11);
    show_list(&list);
    printf("扩容后继续在第12个位置插入数据");
    pos_insert_data_tolist(320,&list,12);
    show_list(&list);
    printf("扩容后继续在第13个位置插入数据");
    pos_insert_data_tolist(420,&list,13);
    show_list(&list);

    printf("删除数据测试：\n");
    printf("110\n");
    pos_delet_data_fromlist(110,&list);
    show_list(&list);
    printf("320\n");
    pos_delet_data_fromlist(320,&list);
    show_list(&list);
    printf("当前表的长度为：%d\n",list.len);
    /* code */
    return 0;
}
